//package net.lab1024.sa.admin.util;
//
//import org.apache.commons.lang3.RandomUtils;
//import org.apache.commons.lang3.StringUtils;
//import org.apache.commons.lang3.SystemUtils;
//import java.net.Inet4Address;
//import java.net.NetworkInterface;
//import java.net.SocketException;
//import java.util.Enumeration;
//import java.lang.management.ManagementFactory;
//import java.lang.management.RuntimeMXBean;
//import java.lang.reflect.Field;
//import java.net.UnknownHostException;
//public final class SnowUtil {
//    /**
//     * @author Monster
//     * @since 2022/4/1 9:47
//     */
//        //序列
//        private long sequence = 0L;
//        //机器编码
//        private long machineId;
//        //数据中心
//        private long datacenterId;
//        //上次时间戳
//        private static long lastTimestamp = -1L;
//
//        // 开始时间截
//        private final static long START_TIME_STAMP = 1659369600000L;
//
//
//        /**
//         * 每一部分占用的位数
//         */
//
//        // 毫秒内自增位数
//        private final static long SEQUENCE_BIT = 12L;
//        // 机器标识位数
//        private final static long MACHINE_BIT = 5L;
//        // 数据中心标识位数
//        private final static long DATACENTER_BIT = 5L;
//
//        /**
//         * 每一部分的最大值
//         */
//        //最大数据中心数量，结果是31
//        private static long DATACENTER_MAX = -1L ^ (-1L << DATACENTER_BIT);
//        //最大机器数量，结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数)
//        private static long MACHINE_MAX = -1L ^ (-1L << MACHINE_BIT);
//
//        //最大序列，这里为4095 (0b111111111111=0xfff=4095)
//        private final static long SEQUENCE_MAX = -1L ^ (-1L << SEQUENCE_BIT);
//
//
//        /**
//         * 每一部分向左的位移
//         */
//        // 机器ID偏左移12位
//        private final static long MACHINE_ID_LEFT = SEQUENCE_BIT;
//        // 数据中心ID左移17位
//        private final static long DATACENTER_ID_LEFT = SEQUENCE_BIT + MACHINE_BIT;
//        // 时间毫秒左移22位
//        private final static long TIME_STAMP_LEFT = SEQUENCE_BIT + MACHINE_BIT + DATACENTER_BIT;
//
//
//        private static SnowUtil snowFlakeIdGenerator2 = null;
//
//
//        static {
//            snowFlakeIdGenerator2 = new SnowUtil();
//        }
//
//
//        private SnowUtil() {
//
//            //获取机器编码
//            this.machineId = this.getMachineNum();
//            //获取进程编码
//            RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
//            this.datacenterId = Long.valueOf(runtimeMXBean.getName().split("@")[0]).longValue();
//
//            //避免编码超出最大值
//            this.machineId = machineId & MACHINE_MAX;
//            this.datacenterId = datacenterId & DATACENTER_MAX;
//
//        }
//
//        public static synchronized long nextId() {
//            return snowFlakeIdGenerator2.getNextId();
//        }
//
//        public synchronized long getNextId() {
//            //获取时间戳
//            long timestamp = getCurrentTimeStamp();
//            //如果时间戳小于上次时间戳则报错
//            if (timestamp < lastTimestamp) {
//                try {
//                    throw new Exception("Clock moved backwards.  Refusing to generate id for " + (lastTimestamp - timestamp) + " milliseconds");
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
//            //如果时间戳与上次时间戳相同
//            if (lastTimestamp == timestamp) {
//                // 当前毫秒内，则+1，与sequenceMask确保sequence不会超出上限
//                sequence = (sequence + 1) & SEQUENCE_MAX;
//                if (sequence == 0) {
//                    // 当前毫秒内计数满了，则等待下一秒
//                    timestamp = tilNextMillis(lastTimestamp);
//                }
//            } else {
//                sequence = 0;
//            }
//            lastTimestamp = timestamp;
//            // ID偏移组合生成最终的ID，并返回ID
//            long nextId = ((timestamp - START_TIME_STAMP) << TIME_STAMP_LEFT) | (datacenterId << DATACENTER_ID_LEFT) | (machineId << MACHINE_ID_LEFT) | sequence;
//            return nextId;
//        }
//
//        /**
//         * 再次获取时间戳直到获取的时间戳与现有的不同
//         *
//         * @param lastTimestamp
//         * @return 下一个时间戳
//         */
//        private long tilNextMillis(final long lastTimestamp) {
//            long timestamp = this.getCurrentTimeStamp();
//            while (timestamp <= lastTimestamp) {
//                timestamp = this.getCurrentTimeStamp();
//            }
//            return timestamp;
//        }
//
//        /**
//         * 返回以毫秒为单位的当前时间
//         */
//        protected long getCurrentTimeStamp() {
//            return System.currentTimeMillis();
//        }
//
//        /**
//         * 获取机器编码
//         *
//         * @return
//         */
//        private long getMachineNum() {
//            long machinePiece;
//            StringBuilder sb = new StringBuilder();
//            Enumeration<NetworkInterface> e = null;
//            try {
//                e = NetworkInterface.getNetworkInterfaces();
//            } catch (SocketException e1) {
//                e1.printStackTrace();
//            }
//            while (e.hasMoreElements()) {
//                NetworkInterface ni = e.nextElement();
//                sb.append(ni.toString());
//            }
//            machinePiece = sb.toString().hashCode();
//            return machinePiece;
//        }
//
//        /**
//         * 生成机器编码(0-31) 方法2
//         */
//        private static Long getMachineId() {
//            try {
//                String hostAddress = Inet4Address.getLocalHost().getHostAddress();
//                int[] ints = StringUtils.toCodePoints(hostAddress);
//                int sums = 0;
//                for (int b : ints) {
//                    sums += b;
//                }
//                return (long) (sums % 32);
//            } catch (UnknownHostException e) {
//                // 如果获取失败，则使用随机数备用
//                return RandomUtils.nextLong(0, 31);
//            }
//        }
//
//
//
//        /**
//         * 生成数据中心编码(0-31)
//         */
//        private static Long getDataCenterId() {
//            int[] ints = StringUtils.toCodePoints(SystemUtils.getHostName());
//            int sums = 0;
//            for (int i : ints) {
//                sums += i;
//            }
//            return (long) (sums % 32);
//        }
//
////        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException {
////            for (int i = 0; i < 1; i++) {
////                Long id = SnowUtil.nextId();
////                System.out.println(id);
////                Class cla = Class.forName(SnowUtil.class.getName());
////                Field[] fields = cla.getDeclaredFields();
////                for (Field field : fields) {
////                    field.setAccessible(true);
////
////                    if (field.getName().equals("machineId")) {
////                        Object value = field.get(new SnowUtil());
////                        System.out.println(field.getName() + " " + value);
////                    }
////                    if (field.getName().equals("datacenterId")) {
////                        Object value = field.get(new SnowUtil());
////                        System.out.println(field.getName() + " " + value);
////                    }
////                    if (field.getName().equals("lastTimestamp")) {
////                        Object value = field.get(new SnowUtil());
////                        System.out.println(field.getName() + " " + value);
////                    }
////                }
////
////            }
////        }
//}
